*********
*
*    Fragmented foes: Affective polarization in the multiparty context of the Netherlands
*    Eelco Harteveld
*	 Electoral Studies
* 
*    REPLICATION SCRIPT
* 
*    This analysis requires two datasets from the LISS Data Archive. See https://dataverse.harvard.edu/dataset.xhtml?persistentId=doi:10.7910/DVN/ANL7OL
*       1. The affective polarisation survey by Eelco Harteveld
*       2. Politics and Values, wave 2019 (cv19k_EN_1.0p.dta)
*
*********

********
* DATA *
********

* Data
use "AffectivePolarisation.dta", clear
gen ownsurvey = 1
merge 1:1 nomem_encr using "cv19k_EN_1.0p.dta", keep(match master)  
gen wave = 19

********************
* DATA PREPARATION *
********************

* Renaming
rename (v2_1-v2_8) (VVD PVV CDA D66 GL SP PvdA FvD)
rename (cv19k211 cv19k213 cv19k215 cv19k216 cv19k218 cv19k214 cv19k212 cv19k305) (psymp_VVD psymp_PVV psymp_CDA psymp_D66 psymp_GL psymp_SP psymp_PvdA psymp_FvD)
rename (outparty refugees benefits) (pos_outparty pos_refugees pos_benefits)
rename party extraparty 

* Voting
gen voteparty = v1
recode voteparty (8 9 10 11 12 14 15 16=.)
lab values voteparty v1
recode voteparty (1=6 "VVD") (2=8 "PVV") (3=5 "CDA") (4=4 "D66") (5=2 "GL") (6=1 "SP") ///
	(7=3 "PvdA") (13=7 "FvD"),  gen(voteparty2)
recode voteparty (6 4 5=1 "In coalition") (nonmissing=0 "Not in coalition"), gen(inparty_coalition)
gen vote19b = voteparty2
recode cv19k308 (2=6) (3=8) (4=5) (5=4) (6=2) (7=1) (8=3) (9/13 15/999=.) (14=7), gen(vote19a)
gen changedparty = .
replace changedparty=0 if vote19a==vote19b & vote19a!=. & vote19b!=.
replace changedparty=1 if vote19a!=vote19b & vote19a!=. & vote19b!=.

* Dyad variables
local party VVD-FvD
local leftright v2_10 v2_11
local refugees v2_12 v2_13
local welfare v2_14 v2_15
local feminism v2_16 v2_17
local education v2_18 v2_19
local etnicity v2_20 v2_21
local religion v2_22-v2_24
local region v2_25 v2_26
local urbanity v2_27 v2_28
local identities party leftright refugees welfare feminism education etnicity religion region urbanity
foreach i in `identities' {
	display "`i'"
	egen min_`i' = rowmin(``i'')
	egen max_`i' = rowmax(``i'')
	gen `i' = max_`i' - min_`i'
	lab var `i' "`i'"
	}

* AP categories	
egen AP_parties = rowmean (party)
egen AP_ideo = rowmean(leftright refugees welfare feminism)
egen AP_demo = rowmean(education-urbanity)

* Other variables
recode oplcat (1 2 3=1 "Low") (4=2 "Middle") (5/6=3 "High"), gen(edu3)
recode oplcat (1/4=1 "Lower educated") (5/6=3 "Higher educated"), gen(edu2)
rename leeftijd age
recode age (19/35=0 "19-35") (36/50=1 "36-50") (51/65=2 "51-65") (66/999=3 "65+"), gen(age4)
recode geslacht (2=0), gen(male)
recode cv19k104 (1=1 "Immigrants can keep culture") (5=5 "Immigrants should adapt") (99=.), gen(immi5)
recode cv19k103 (1=1 "Anti-redistribution") (5=5 "Pro-redistribution") (99=.), gen(redist5)
recode cv19k101 (0=0 "Left") (10=10 "Right") (999=.), gen(lr)
recode lr (0/4=1 "Left") (5=2 "Center") (6/10=3 "Right"), gen(lr3)
recode lr (0/1=1 "Far left") (2/4=2 "Center left") (5=3 "Center") (6/8=4 "Center right") (9/10=5 "Far right"), gen(lr5)
recode cv19k012 (3=1 "Low") (2=2 "Middle") (1=3 "High") (99=.), gen(polint)
recode cv19k012 (3 2=1 "Low") (1=2 "High") (99=.), gen(polint2)
rename (cv19k002 cv19k003 cv19k166) (news_tv news_online news_paper)
rename cv19k199 partisan
rename cv19k200 attracted
recode cv19k017 (0/4=0 "Low") (5=1) (6=2) (7/10=3 "High") (11/9999=.), gen(poltrust4)
recode sted (5=1 "Least") (4=2) (3=3) (2=4) (1=5 "Most"), gen(urb5)
recode psymp_* (999=.)
alpha cv19k050-cv19k052, item gen(inteff)
replace inteff = 1-inteff
gen pid = partisan
gen partyID = 0
replace partyID = 1 if attracted==1 | pid==1
lab var partyID "Party identity"

* Labels
lab define Immi2 1 "Anti-refugees" 2 "Pro-refugees"
lab values pos_refugees Immi2
lab define news_online 0 "No news online" 1 "News online"
lab values news_online news_online
lab var news_online "News: online"
lab var partisan "Partisan"
lab var edu3 "Education"
lab var lr3 "Left-right self-placement"
lab var polint "Political interest"
lab var polint2 "Political interest"
lab var age4 "Age"
lab var poltrust4 "Political trust"
lab var urb5 "Urbanity"
lab var news_tv "News: tv"
lab var news_paper "News: paper"
lab var immi5 "Immigrant attitude" 
lab var redist5 "Redistribution attitude"
lab var lr5 "Left-right"

* Identifier
gen id = _n


************
* ANALYSIS *
************

* PART I: WITHOUT RESHAPING
* -------------------------

* (1) Figure 3
preserve
drop if voteparty==.
foreach var of varlist SP GL PvdA D66 CDA VVD FvD PVV {
	bys voteparty2: egen sd_`var' = sd(`var')
	}
collapse SP GL PvdA D66 CDA VVD FvD PVV, by(voteparty2)
mkmat SP GL PvdA D66 CDA VVD FvD PVV, matrix(therm)
display `therm'
restore
matrix list therm
heatplot therm, cuts(0(5)100) colors(hcl, bluered) size  ///
	scheme(538w) ///
	ylabel(1 "Radical left {bf:SP}" 2 "Greens {bf:GL}" 3 "Social democrats {bf:PvdA}" 4 "Social liberals {bf:D66}" 5 "Christian democrats {bf:CDA}" 6 "Conservative liberals {bf:VVD}" 7 "Populist radical right {bf:FvD}" 8 "Populist radical right {bf:PVV}") ///
	xlabel(1 "{bf:SP}" 2 "{bf:GL}" 3 "{bf:PvdA}" 4 "{bf:D66}" 5 "{bf:CDA}" 6 "{bf:VVD}" 7 "{bf:FvD}" 8 "{bf:PVV}") ///
	xtitle("") ytitle("") legend(title("")) xsize(6.5) ramp(right space(18) labels(0 "Negative" 50 "Neutral" 100 "Positive") subtitle("")) ///
	values(format(%9.1f) mlabsize(vsmall)) ///
	ytitle("In-party") xtitle("Evaluated group")
graph export "Figure 3.tif", replace width(4000)

* PART II: RESHAPED TO RESPONDENT-PARTY DYADS
* -------------------------------------------

* Reshape the data first through the script below
{
rename (VVD PVV CDA D66 GL SP PvdA FvD) (therm1 therm2 therm3 therm4 therm5 therm6 therm7 therm13)
rename (psymp_*) ( psymp1  psymp2  psymp3  psymp4  psymp5  psymp6  psymp7  psymp13)
tab v1, gen(vote)
tab cv19k310, gen(attrac)
tab cv19k309, gen(adher)
lab define parties 1 "VVD" 2 "PVV" 3 "CDA" 4 "D66" 5 "GL" 6 "SP" 7 "PvdA" 8 "CU" 9 "PvdD" 10 "50Plus" 11 "SGP" 12 "Denk" 13 "FvD"
rename party partydist
reshape long therm vote symp attrac adher psymp, i(id) j(party)
lab values party parties
recode attrac adher (.=0)
recode party (1=1003) (2=1017) (3=1001) (4=1004) (5=1005) (6=1014) (7=1002) (8=1016) (13=1051), gen(party_id)
recode party (1=6 "VVD") (2=8 "PVV") (3=5 "CDA") (4=4 "D66") (5=2 "GL") (6=1 "SP") (7=3 "PvdA") (13=7 "FvD") (nonmissing=.),  gen(party2)
recode party2 (6 4 5=1 "In coalition") (nonmissing=0 "Not in coalition"), gen(outparty_coalition)
gen coalitionpartner = 0
replace coalitionpartner=1 if inparty_coalition==1 & outparty_coalition==1
merge m:m party_id using "d:\Dropbox\From disagree to disapprove\Various data\CHES\CHES2017.dta", gen(mergeches) force
drop if id==.
rename immigrate_policy immigr
foreach var of varlist lrgen lrecon galtan immigr {
	bys id: egen own_`var'B = mean(`var') if vote==1
	bys id: egen own_`var' = mean(own_`var'B)
	gen dist_`var' = abs(own_`var' - `var')
	egen std_dist_`var' = std(dist_`var')
	}
recode party (2 13=1) (nonmissing=0), gen(PRR)
bys party: egen partysize = mean(vote)
bys id: egen sd_therm_id = sd(therm)
lab var std_dist_lrecon "Economy (z)"
lab var std_dist_immigr "Culture  (z)"
lab var vote "Yes"
lab var inteff "Internal efficacy"
lab var psymp "Party sympathy"
}

* (1) Correlations
corr psymp therm 
corr psymp therm if changedparty==0
mean psymp if vote==0, over(party2)
mean therm if vote==0, over(party2)

* (2) Figure 1
keep if therm!=.
local vars1 "ib6.party2 ib3.lr5 i.partyID ib1.polint2"
mixed therm `vars1' if vote==0 || id: 
estimates store m1
mixed therm psymp `vars1' if vote==0  || id: 
estimates store m2
coefplot m1 m2, scheme(cleanplots) xline(0) drop(_cons *.party) ysize(5) ///
	headings(1.party2="{bf:Evaluated party} (ref: VVD)" /// 
	1.edu3="{bf: Education} (ref: middle)" 2.polint2="{bf: Political interest} (ref: low)" ///
	1.lr5="{bf: Ideology} (ref: center)" 1.partyID="{bf: Party identity}" ///
	psymp="{bf: Party sympathy}") ///
	legend(order(2 "Not controlling for {it:Party sympathy}" 4 "Controlling for {it:Party sympathy}")) ///
	xtitle("Effect on {it:Partisan sympathy}")
graph export "Figure 1.tif", replace width(4000)
estout m1 m2 using "Appendix C.xls", cells(b(star fmt(3)) se(par(`"="("' `")""') fmt(3))) starlevels(+ 0.10 * 0.05 ** 0.01 *** 0.001)  varlabels(_cons Intercept) noomit nobase label varwidth(40) replace

* (3) Figure 4
xtmixed therm ib6.party2 ib6.voteparty2 if vote==0 || id:
estimates store m1
xtmixed therm std_dist_lrecon std_dist_immigr vote ib6.party2 ib6.voteparty2  if vote==0  || id: 
estimates store m2
xtmixed therm std_dist_lrecon std_dist_immigr vote ib6.party2 ib6.voteparty2 psymp  if vote==0  || id: 
estimates store m3
coefplot m1 m2 m3, drop(_cons) scheme(cleanplots) xline(0) ///
	order(std_dist_lrecon std_dist_immigr vote b2.polint ib2.edu3 i.age4 ib6.party2 ib6.voteparty2 ) ///
	headings(1.party2="{bf:Evaluated party} (ref: VVD)" std_dist_lrecon="{bf:Ideological distance}" 1.voteparty2="{bf: Inparty} (ref: VVD)" /// 
	vote="{bf:Voted for party?}" 1.edu3="{bf: Education} (ref: middle)" 1.polint="{bf: Political interest} (ref: middle)" ///
	1.age4="{bf: Age} (ref: below 35)" psymp="{bf: Party sympathy}") /// 7.party2="{it:Populist Radical Right parties}"  7.voteparty2="{it:Populist Radical Right parties}" 
	legend(order(2 "Parties only" 4 "+ ideological distance" 6 "+ party sympathy")) ysize(8) legend(position(4)) ///
	xsize(9.5)
graph export "Figure 4.tif", replace width(3500)
estout m1 m2 m3 using "Appendix E.xls", cells(b(star fmt(3)) se(par(`"="("' `")""') fmt(3))) starlevels(+ 0.10 * 0.05 ** 0.01 *** 0.001)  varlabels(_cons Intercept) noomit nobase label varwidth(40) replace

* (4) Appendix B
twoway scatter psymp therm, mcolor(%75) || lfit psymp therm, lwidth(1.5) lcolor(%50) ||, by(party2, note("")) scheme(538w) ///
	ytitle("Party sympathy") xtitle("Partisan sympathy") ysize(8) legend(order(1 "Observations" 2 "Linear fit"))
graph export "Appendix B.tif", replace width(3000)


* PART III: RESHAPED TO RESPONDENT-OUTGROUP DYADS
* -----------------------------------------------

* Note: run the reshaping command below after the data preparation section above, but without reshaping to the respondent-party dyads.
{
lab define group 0 "Party lines" 1 "Left-right" 2 "Refugees" 3 "Welfare" 4 "Gender roles" 5 "Education" 6 "Etnicity" 7 "Religion" 8 "Region" 9 "Urbanity"
egen min0 = rowmin(VVD-FvD)
egen min1 = rowmin(v2_10 v2_11)
egen min2 = rowmin(v2_12 v2_13)
egen min3 = rowmin(v2_14 v2_15)
egen min4 = rowmin(v2_16 v2_17)
egen min5 = rowmin(v2_18 v2_19)
egen min6 = rowmin(v2_20 v2_21)
egen min7 = rowmin(v2_22 v2_23 v2_24) // with v2_24?
egen min8 = rowmin(v2_25 v2_26)
egen min9 = rowmin(v2_27 v2_28)
egen max0 = rowmax(VVD-FvD)
egen max1 = rowmax(v2_10 v2_11)
egen max2 = rowmax(v2_12 v2_13)
egen max3 = rowmax(v2_14 v2_15)
egen max4 = rowmax(v2_16 v2_17)
egen max5 = rowmax(v2_18 v2_19)
egen max6 = rowmax(v2_20 v2_21)
egen max7 = rowmax(v2_22 v2_23)
egen max8 = rowmax(v2_25 v2_26)
egen max9 = rowmax(v2_27 v2_28)
egen rowsum0 = rowtotal(VVD-FvD)
egen rowobs0 = rownonmiss(VVD-FvD)
gen outgr0 = (rowsum0 - max0) / (rowobs0 - 1)
egen rowsum7 = rowtotal(v2_22 v2_23 v2_24)
egen rowobs7 = rownonmiss(v2_22 v2_23 v2_24)
gen outgr7 = (rowsum7 - max7) / (rowobs7 - 1)
drop id
gen id = _n
reshape long min max outgr, i(id) j(group)
lab values group group
lab var group "Issue"
gen dist = max-min
}

* (1) Figure 2
preserve
recode group (0=1 "Party preference") (4=2 "Gender roles attitude") (2=3 "Refugees attitude") (3=4 "Welfare attitude") (7=5 "Religion") (1=6 "Left or Right ideology") (6=7 "Ethnicity") (8=8 "Region") (5=9 "Education") (9=10 "Urbanity"), gen(group3)
rename (min outgr max) (eval1 eval2 eval3)
drop id
gen id = _n
recode group (0=10 "Party lines") (1=6 "Left-Right") (2=9 "Refugees") (3=7 "Welfare") (4=8 "Gender roles") ///
	(5=2 "Education") (6=4 "Etnicity") (8=1 "Region") (9=3 "Urbanity") (7=5 "Religion"), gen(group2) 
reshape long eval, i(id) j(dimension)
regress eval i.dimension##i.group3
margins, over(dimension group3)
marginsplot, scheme(cleanplots) x(group3) title("") ///
	ytitle("Social distance to outgroup", size(small)) ///
	ciopts(lcolor(%50)) ///
	legend(order(4 "Outgroup ({it:lowest score})" 5 "Outgroup ({it:mean score})" 6 "Ingroup ({it:highest score})" )) recast(scatter) horizontal ///
	ytitle("") yscale(reverse) xtitle("Thermometer score") xlabel(0(10)100) ysize(4.5) legend(position(4))
graph export "Figure 2.tif", replace width(4000)
restore

* (2) Appendix D
regress min i.group##i.polint
margins, over(group polint)
mplotoffset, offset(0.1) xsize(8) xlabel(0 1 2 3 4 5 6 7 8 9) xtitle("Political                                                                                  Non-political        ", size(small) color(%70)) scheme(cleanplots) ylabel(0(10)80) ytitle("Thermometer score handed out to outgroup", size(small)) xline(4.5) title("(a) By political interest") recast(scatter) name(gr1, replace)
regress min i.group##i.lr5
margins, over(group lr5)
mplotoffset, offset(0.1) xsize(8) xlabel(0 1 2 3 4 5 6 7 8 9) xtitle("Political                                                                                  Non-political        ", size(small) color(%70)) scheme(cleanplots) ylabel(0(10)80) ytitle("Thermometer score handed out to outgroup", size(small)) xline(4.5) title("(b) By left-right ideology") recast(scatter) name(gr2, replace)
graph combine gr1 gr2, cols(1) ysize(4.7)
graph export "Appendix D.tif", replace width(4000)
